<template>
  <div>
    <el-input
      v-model="title"
      placeholder="请输入文章标题"
      type="text"
      @focus="changeValue"
    />
    <div class="row" style="align-items: center">
      文章类型:
      <el-select
        v-model="articleType"
        placeholder="请选择"
        style="margin: 8px"
        :disabled="type === 'edit'"
      >
        <el-option
          v-for="item in typeOptions"
          :key="item.value"
          :label="item.label"
          :value="item.value"
        />
      </el-select>
    </div>
    <div style="border: 1px solid #ccc; margin-top: 10px">
      <Toolbar
        :editor="editorRef"
        :defaultConfig="toolbarConfig"
        :mode="mode"
        style="border-bottom: 1px solid #ccc"
      />
      <Editor
        id="editor"
        :defaultConfig="editorConfig"
        :mode="mode"
        v-model="valueHtml"
        style="height: 600px; overflow-y: hidden"
        @onCreated="handleCreated"
        @onFocus="changeValue"
      />
    </div>
    <div class="uploadFile">
      <el-upload
        v-model:file-list="fileList"
        class="upload-demo"
        action="http://119.29.216.71:35802/api/upload"
        :auto-upload="false"
        multiple
        :before-remove="beforeRemove"
        :limit="5"
        :on-exceed="handleExceed"
        element-loading-text="上传中..."
        v-loading="loading"
      >
        <template #trigger>
          <el-button type="primary">选择文件</el-button>
        </template>
        <el-button
          style="margin-left: 12px; margin-bottom: 4px"
          type="success"
          @click="submitUpload"
        >
          上传文件
        </el-button>
        <template #tip>
          <div class="el-upload__tip">文件最大不超过4MB</div>
        </template>
      </el-upload>
    </div>
  </div>
</template>

<script lang="ts">
import '@wangeditor/editor/dist/css/style.css'
import { onBeforeUnmount, ref, shallowRef } from 'vue'
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
import axios from 'axios'
import { ElMessage, ElMessageBox } from 'element-plus'
import type { UploadProps, UploadUserFile } from 'element-plus'

export default {
  components: { Editor, Toolbar },
  props: ['articleId', 'type'],
  setup(props) {
    // 编辑器实例，必须用 shallowRef，重要！
    const editorRef = shallowRef()
    const title = ref('') //文章标题
    const articleType = ref('')
    // 内容 HTML
    const valueHtml = ref('')
    const fileList = ref<UploadUserFile[]>([]) //文件列表
    const article = ref<any>(null) //文章
    const loading = ref(false) //是否处于文件上传中
    const isFirstChange = ref(false)
    const haveChange = ref(false) //是否有修改

    const typeOptions = [
      {
        label: '党建工作',
        value: '党建工作',
      },
      {
        label: '研究会动态',
        value: '研究会动态',
      },
      {
        label: '行业风采',
        value: '行业风采',
      },
      {
        label: '通知公告',
        value: '通知公告',
      },
      {
        label: '示范推广',
        value: '示范推广',
      },
      {
        label: '会员活动',
        value: '会员活动',
      },
      {
        label: '会员须知',
        value: '会员须知',
      },
      {
        label: '行业动态',
        value: '行业动态',
      },
      {
        label: '公示公告',
        value: '公示公告',
      },
      {
        label: '政策法规',
        value: '政策法规',
      },
      {
        label: '招商信息',
        value: '招商信息',
      },
      {
        label: '下载申请表',
        value: '下载申请表',
      },
    ]

    const init = () => {
      title.value = ''
      valueHtml.value = ''
      fileList.value = []
      articleType.value = '通知公告'
    }

    // 根据文章id获取文章内容
    const setArticle = async (arti: any) => {
      let list = JSON.parse(JSON.stringify(arti.attachment))
      article.value = arti
      valueHtml.value = arti.content
      title.value = arti.title
      articleType.value = arti.type
      fileList.value = eval(list)
    }
    // 获取token
    const getToken = () => {
      return `Bearer ${window.localStorage.getItem('token')}`
    }
    //上传文件
    const upload = (file: any) => {
      return axios({
        url: 'http://119.29.216.71:35802/api/upload',
        method: 'post',
        data: {
          upload: file,
        },
        headers: {
          'Content-Type': 'multipart/form-data',
        },
      })
    }
    //wangEditor富文本编辑器配置
    const toolbarConfig = {}
    const editorConfig: any = {
      placeholder: '请输入内容...', // 配置默认提示
      // readOnly: true,
      MENU_CONF: {},
    }
    editorConfig.MENU_CONF['uploadImage'] = {
      fieldName: 'form-data',
      // 单个文件的最大体积限制，默认为 2M
      maxFileSize: 4 * 1024 * 1024, // 1M
      // 最多可上传几个文件，默认为 100
      maxNumberOfFiles: 10,
      allowedFileTypes: ['image/*'],
      metaWithUrl: false,

      // 自定义增加 http  header
      headers: {
        Authorization: getToken(),
      },
      timeout: 5 * 1000, // 5 秒
      async customUpload(file: any, insertFn: any) {
        // 文件上传
        // 这里根据自己项目封装情况，设置上传地址
        axios.defaults.headers.common[
          'Authorization'
        ] = `Bearer ${window.localStorage.getItem('token')}`
        let result = await upload(file)
        // 插入到富文本编辑器中，主意这里的三个参数都是必填的，要不然控制台报错：typeError: Cannot read properties of undefined (reading 'replace')
        insertFn(
          result.data.data.url,
          result.data.data.name,
          result.data.data.name
        )
      },
    }
    //选择文件数超出限制
    const handleExceed: UploadProps['onExceed'] = (files, uploadFiles) => {
      ElMessage.warning(
        `附件最多上传五个, 您这次选择 ${files.length} 个文件, 共 ${
          files.length + uploadFiles.length
        } 个文件`
      )
    }

    const beforeRemove: UploadProps['beforeRemove'] = (uploadFile) => {
      return ElMessageBox.confirm(`取消文件 ${uploadFile.name} 的上传？`).then(
        () => true,
        () => false
      )
    }

    // 富文本组件销毁时，也及时销毁编辑器，重要！
    onBeforeUnmount(() => {
      const editor = editorRef.value
      if (editor == null) return
      editor.destroy()
    })

    // 编辑器回调函数
    const handleCreated = (editor: any) => {
      editorRef.value = editor // 记录 editor 实例，重要！
    }
    const changeValue = () => {
      if (isFirstChange.value) {
        haveChange.value = true
      }
      isFirstChange.value = true
    }
    const customPaste = (editor: any, event: any, callback: any) => {
      callback(true) // 返回 true ，继续默认的粘贴行为
    }
    //获取文件列表，仅有name和url
    const getFileUrlList = () => {
      let fileUrlList: { name: string; url: string | undefined }[] = []
      fileList.value.forEach((item) => {
        fileUrlList.push({
          name: item.name,
          url: item.url,
        })
      })
      return fileUrlList
    }
    //更新文章
    const updateArticle = async () => {
      console.log(articleType.value)

      let fileUrlList = getFileUrlList()
      await axios
        .put('/api/updateEssayById', {
          id: article.value.id,
          title: title.value,
          author: article.value?.author,
          content: valueHtml.value,
          time: article.value.time,
          type: article.value.value,
          attachment: JSON.stringify(fileUrlList),
        })
        .then(() => {
          ElMessage.success('修改成功')
          isFirstChange.value = false
          haveChange.value = false
          changeValue
        })
        .catch(() => {
          ElMessage.error('修改失败')
          return false
        })
      return true
    }
    //增加文章
    const addArticle = async () => {
      let fileUrlList = getFileUrlList()

      await axios
        .post('/api/addEssay', {
          title: title.value,
          content: valueHtml.value,
          type: articleType.value,
          attachment: JSON.stringify(fileUrlList),
        })
        .then(() => {
          ElMessage.success('添加成功')
          isFirstChange.value = false
          haveChange.value = false
          return true
        })
        .catch(() => {
          ElMessage.error('添加失败')
          return false
        })
      return true
    }
    //保存文章
    const save = async () => {
      if (title.value === '') {
        ElMessage.error('文章标题不能为空')
        return false
      }
      for (let i = 0; i < fileList.value.length; i++) {
        //如果有文件url为空，说明有文件未上传
        if (
          fileList.value[i].url === undefined ||
          fileList.value[i].url === null ||
          fileList.value[i].url === ''
        ) {
          ElMessage.error('有文件未上传')
          return false
        }
      }
      //编辑或者新增,返回是否成功
      if (props.type === 'edit') {
        return await updateArticle()
      } else if (props.type === 'add') {
        return await addArticle()
      }
      return false
    }

    const submitUpload = async () => {
      if (fileList.value.length === 0) {
        ElMessage.warning('未选择文件')
        return
      }
      loading.value = true
      // fileList.value = []
      for (let i = 0; i < fileList.value.length; i++) {
        //之前上传过的，跳过
        if (
          fileList.value[i].url != undefined &&
          fileList.value[i].url != null &&
          fileList.value[i].url != ''
        ) {
          continue
        }
        await axios({
          url: 'http://119.29.216.71:35802/api/upload',
          method: 'post',
          data: {
            upload: fileList.value[i].raw,
          },
          headers: {
            'Content-Type': 'multipart/form-data',
          },
        })
          .then((res) => {
            fileList.value[i].url = res.data.data.url
          })
          .catch(() => {
            ElMessage.error('上传失败')
            loading.value = false
            return false
          })
      }
      loading.value = false
      ElMessage.success('上传成功')
      return true
    }

    return {
      editorRef,
      mode: 'default',
      valueHtml,
      toolbarConfig,
      editorConfig,
      handleCreated,
      changeValue,
      customPaste,
      save,
      title,
      fileList,
      beforeRemove,
      handleExceed,
      submitUpload,
      loading,
      setArticle,
      init,
      haveChange,
      articleType,
      typeOptions,
    }
  },
}
</script>

<style scoped>
.uploadFile {
  margin: 12px 0 12px 0;
}
</style>
